﻿#region Copyright(C) 2012 NCS Pte. Ltd. All rights reserved.

// ==================================================================================================
// Copyright(C) 2012 NCS Pte. Ltd. All rights reserved.
//
// SYSTEM NAME	:   iConnect.Azure Application Framework
// COMPONENT ID :   NCS.IConnect.Azure.Diagnostics.AzureStorage.AzureStorageAccount
// COMPONENT DESC:  	
//
// CREATED DATE/BY:  08 June 2012 / Lu Ya Ming
//
// REVISION HISTORY:	
// DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// ==================================================================================================

#endregion

using System;
using System.Globalization;

using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;

using NCS.IConnect.Cloud.Core.Properties;

namespace NCS.IConnect.Cloud.Core.AzureStorage
{
    /// <summary>
    /// The Azure storage account.
    /// </summary>
    public class AzureStorageAccount : ICloudStorageAccount
    {
        private readonly CloudStorageAccount account;

        /// <summary>
        /// Initializes a new instance of the <see cref="AzureStorageAccount"/> class.
        /// </summary>
        /// <param name="storageAccount">The storage account.</param>
        public AzureStorageAccount(string storageAccount)
            : this(GetCloudStorageAccount(storageAccount))
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AzureStorageAccount"/> class.
        /// </summary>
        /// <param name="account">The account.</param>
        public AzureStorageAccount(CloudStorageAccount account)
        {
            this.account = account;
        }

        /// <summary>
        /// Gets the development storage account.
        /// </summary>
        /// <value>
        /// The development storage account.
        /// </value>
        public static ICloudStorageAccount DevelopmentStorageAccount
        {
            get
            {
                return new AzureStorageAccount(CloudStorageAccount.DevelopmentStorageAccount);
            }
        }

        /// <summary>
        /// Gets the credentials.
        /// </summary>
        /// <value>
        /// The credentials.
        /// </value>
        public StorageCredentials Credentials
        {
            get
            {
                return this.account.Credentials;
            }
        }

        /// <summary>
        /// Parses the specified storage account.
        /// </summary>
        /// <param name="storageAccount">The storage account.</param>
        /// <returns></returns>
        public static ICloudStorageAccount Parse(string storageAccount)
        {
            return new AzureStorageAccount(GetCloudStorageAccount(storageAccount));
        }

        /// <summary>
        /// Creates the cloud table client.
        /// </summary>
        /// <returns></returns>
        public ICloudTableClient CreateCloudTableClient()
        {
            return new AzureStorageCloudTableClient(this.account.CreateCloudTableClient());
        }

        /// <summary>
        /// Creates the cloud BLOB client.
        /// </summary>
        /// <returns></returns>
        public ICloudBlobClient CreateCloudBlobClient()
        {
            return new AzureStorageCloudBlobClient(this.account.CreateCloudBlobClient());
        }

        /// <summary>
        /// Gets the cloud storage account.
        /// </summary>
        /// <param name="storageAccount">The storage account.</param>
        /// <returns></returns>
        /// <exception cref="NCS.IConnect.Cloud.Core.AzureStorage.AzureStorageException">
        /// </exception>
        private static CloudStorageAccount GetCloudStorageAccount(string storageAccount)
        {
            if (storageAccount.Contains("="))
            {
                try
                {
                    return CloudStorageAccount.Parse(storageAccount);
                }
                catch (FormatException ex)
                {
                    throw new AzureStorageException(Resources.AzureStorageConnectionStringIsInvalid, ex);
                }
            }
            else
            {
                try
                {
                    var account = CloudStorageAccount.FromConfigurationSetting(storageAccount);

                    if (account == null)
                    {
                        throw new AzureStorageException(
                            string.Format(
                                CultureInfo.CurrentCulture,
                                Resources.AzureStorageConnectionStringCouldNotBeRetrieveFromConfiguration,
                                storageAccount));
                    }

                    return account;
                }
                catch (InvalidOperationException ex)
                {
                    throw new AzureStorageException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.AzureStorageConnectionStringCouldNotBeRetrieveFromConfigurationNoPublisher,
                            storageAccount),
                        ex);
                }
                catch (RoleEnvironmentException ex)
                {
                    throw new AzureStorageException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.AzureStorageConnectionStringCouldNotBeRetrieveFromConfigurationRoleEnvironmentException,
                            storageAccount),
                        ex);
                }
            }
        }

    }
}
